/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "VssLog.h"
#include <comutil.h>

VssLogWrapper::VssLogWrapper()
{}

VssLogWrapper::~VssLogWrapper()
{}

bool VssLogWrapper::InitializeBackupContect(const VSS_SNAPSHOT_CONTEXT &context)
{
    CHECK_BOOL_RETURN(InitializeVssComponent(), "InitializeVssComponent", false);

    HRESULT hr = m_pVssObject->InitializeForBackup();
    CHECK_HR_RETURN(hr, "InitializeForBackup", false);

    hr = m_pVssObject->SetContext(context);
    CHECK_HR_RETURN(hr, "SetContext", false);

    hr = m_pVssObject->SetBackupState(true, false, VSS_BT_INCREMENTAL, false);
    CHECK_HR_RETURN(hr, "SetBackupState", false);

    return true;
}

std::map<std::string, std::string> VssLogWrapper::ObtainBackupFileSet(CComPtr<IVssExamineWriterMetadata> writerMetadata,
    const UINT componentCount, const std::string guid, std::vector<std::string> exposeList,
    std::vector<std::wstring> wVolumePathList)
{
    std::map<std::string, std::string> pathList;
    std::string finalLogicalPath;
    CHECK_BOOL_RETURN(GetLogicalPath(writerMetadata, componentCount, guid, finalLogicalPath), "GetLogicalPath", {});

    for (UINT i = 0; i < componentCount; i++) {
        CComPtr<IVssWMComponent> pSonComponent;
        HRESULT sonHr = writerMetadata->GetComponent(i, &pSonComponent);
        CHECK_HR_RETURN(sonHr, "GetComponent", {});

        PVSSCOMPONENTINFO sonComponentInfo;
        sonHr = pSonComponent->GetComponentInfo(&sonComponentInfo);
        CHECK_HR_RETURN(sonHr, "GetComponentInfo", {});

        std::string componentName = (std::string)_com_util::ConvertBSTRToString(sonComponentInfo->bstrLogicalPath);
        if (componentName == finalLogicalPath) {
            DoAddComponentToPathList(sonComponentInfo, pSonComponent, exposeList, wVolumePathList, pathList);
        }
    }
    return pathList;
}

bool VssLogWrapper::DoAddComponentToPathList(PVSSCOMPONENTINFO sonComponentInfo, CComPtr<IVssWMComponent> pSonComponent,
    std::vector<std::string> exposeList, std::vector<std::wstring> wVolumePathList,
    std::map<std::string, std::string> &pathList)
{
    for (UINT j = 0; j < sonComponentInfo->cFileCount; j++) {
        CComPtr<IVssWMFiledesc> pFiledesc;
        HRESULT sonHr = pSonComponent->GetFile(j, &pFiledesc);
        CHECK_HR_RETURN(sonHr, "GetFile", false);

        BSTR bstrPath;
        sonHr = pFiledesc->GetPath(&bstrPath);
        CHECK_HR_RETURN(sonHr, "GetPath", false);
        std::string tempBstrPath = (std::string)_com_util::ConvertBSTRToString(bstrPath);

        (tempBstrPath[tempBstrPath.size() - 1] != '\\') ? tempBstrPath += "\\" : tempBstrPath;
        BSTR bstrFileName;
        sonHr = pFiledesc->GetFilespec(&bstrFileName);
        CHECK_HR_RETURN(sonHr, "GetFilespec", false);

        std::string strFileName = (std::string)_com_util::ConvertBSTRToString(bstrFileName);
        std::string filePostFix = strFileName.substr(strFileName.size() - POSTFIX_POS, POSTFIX_POS);
        if (filePostFix == ".log" && strFileName[strFileName.size() - WILDCARD_POS == '*']) {
            AddLogComponentToPathList(tempBstrPath, strFileName, exposeList, wVolumePathList, pathList);
        }
    }
}